<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!--DOCTYPE html-->
<html>
<head>
	<title>Web IDE</title>
	<script src="http://code.jquery.com/jquery-latest.js"></script>
	<script type="text/javascript">
		/**
		* Returns the value of the selected radio button in the radio group, null if
		* none are selected, and false if the button group doesn't exist
		*
		* @param {radio Object} or {radio id} el
		* OR
		* @param {form Object} or {form id} el
		* @param {radio group name} radioGroup
		*/
		function $RF(el, radioGroup) {
			if($(el).type && $(el).type.toLowerCase() == 'radio') {
				var radioGroup = $(el).name;
				var el = $(el).form;
			} else if ($(el).tagName.toLowerCase() != 'form') {
				return false;
			}
		 
			var checked = $(el).getInputs('radio', radioGroup).find(
				function(re) {return re.checked;}
			);
			return (checked) ? $F(checked) : null;
		}
	</script>
	<script type="text/javascript">
		var VIEW_NAME = "viewWindow";
		var VIEW_FRAME_ID = "viewFrame";
		var viewWindow = null;
		var viewFrame = null;
		var VISUAL_EDITOR_NAME = "visualEditor";
		var visualEditorWindow = null;
		
		// Add an iframe to parent that will display the working page
		function appendViewIframe(parent)
		{
			var doc = parent.ownerDocument;
			viewFrame = doc.createElement("iframe");
			viewFrame.setAttribute("id", VIEW_FRAME_ID);
			viewFrame.setAttribute("name", VIEW_NAME);
			parent.appendChild(viewFrame);
		}
		
		// Remove a view iframe
		function removeViewIframe()
		{
			if (viewFrame != null)
			{
				removeElement(viewFrame);
			}
		}
		
		// Have an element remove itself from it's associated dom
		function removeElement(element)
		{
			element.parentNode.removeChild(element);
		}
		
		// Open a new window that will display the working page
		function openViewWindow()
		{
			viewWindow = window.open("about:blank", VIEW_NAME);
		}
		
		// Closes the open view window if it is open
		function closeViewWindow()
		{
			if (viewWindow != null)
			{
				viewWindow.close();
			}
		}
		
		// Get the value of a radio by name
		function getCheckedRadio(name, doc)
		{
			if (doc == undefined)
			{
				doc = document;
			}
			var inputs = doc.body.getElementsByTagName("input");
			for(var i in inputs)
			{
				if (inputs[i].getAttribute("type") == "radio" && inputs[i].checked)
				{
					return inputs[i].value;
				}
			}
		}
		
		// Opens a view based on the given viewType
		function openView(viewType)
		{
			if (viewType == undefined)
			{
				viewType = getCheckedRadio("viewType");
			}
			if (viewType == "window")
			{
				openViewWindow();
			}
			else if (viewType == "iframe")
			{
				appendViewIframe(document.body);
				openViewWindow();
			}
		}
		
		// Close a view based on the viewType
		function closeView(viewType)
		{
			if (viewType == undefined)
			{
				viewType = getCheckedRadio("viewType");
			}
			if (viewType == "window")
			{
				closeViewWindow();
			}
			else if (viewType == "iframe")
			{
				removeViewIframe();
			}
		}
		
		// Close associated windows when main window closes
		window.onbeforeunload = function()
		{
			closeViewWindow();
			closeVisualEditorWindow();
		}
		
		// Open a visual editor window
		function openVisualEditorWindow()
		{
			visualEditorWindow = window.open("about:blank", VISUAL_EDITOR_NAME);
		}
		
		// Close a visual editor window
		function closeVisualEditorWindow()
		{
			if (null != visualEditorWindow)
			{
				visualEditorWindow.close();
			}
		}
		
		// Get the raw html from the editor
		function getRawHtml()
		{
			return document.getElementById("rawHtml").value;
		}
		
		// Set the raw html of the editor
		function setRawHtml(html)
		{
			document.getElementById("rawHtml").value = html;
		}
		
		// Update the view window. Closes and reopens window to reset it.
		function writeViewWindowHtml()
		{
			//var node = viewWindow.document.documentElement;
			closeView();
			openView();
			//var parent = rawHtmlElement.parentNode;
			//parent.removeChild(rawHtmlElement);
			//rawHtmlElement = document.createElement("iframe");
			//rawHtmlElement.name = "viewWindow";
			//var rawHtml = rawHtmlElement.value;
			//var div = viewWindow.document.createElement('div');
			//div.appendChild(node.cloneNode(true));
			//viewWindow.document.replaceChild(div.firstChild, node);
			//viewWindow.document.documentElement = div.firstChild;
			//div = null;
			viewWindow.document.write(getRawHtml());
			viewWindow.document.close();
		}
		
		// Push data from the editor to the visual editor window
		function writeVisualEditorWindowHtml()
		{
			closeVisualEditorWindow();
			openVisualEditorWindow();
			visualEditorWindow.addEventListener("load", visualEditorWindowOnload, false);
			visualEditorWindow.document.write(getRawHtml());
			visualEditorWindow.document.close();
		}
		
		// Visual editor onload callback
		function visualEditorWindowOnload()
		{
			makeEditable(visualEditorWindow.document);
			//visualEditorWindow.document.editorPallet = makeEditorPallet(visualEditorWindow.document);
			//visualEditorWindow.document.body.appendChild(visualEditorWindow.document.editorPallet);
			//visualEditorWindow.document.addEventListener("load", visualEditorDocumentOnload, false);
		}
		
		// Create an editor pallet
		function makeEditorPallet(doc)
		{
			var div = doc.createElement("div");
			div.style.width = "400px";
			div.style.height = "600px";
			div.style.position = "fixed";
			div.style.backgroundColor = "red";
			return div;
		}
		
		// Makes the region the element contains editable
		function makeEditable(element)
		{
			$(element).click(function(e) {
				var clickX = e.pageX
					,clickY = e.pageY
					,list
					,$list
					,offset
					,range;

				$list = $(element).children().filter(function() {
					offset = $(this).offset();
					range = {
						x: [ offset.left,
							offset.left + $(this).outerWidth() ],
						y: [ offset.top,
							offset.top + $(this).outerHeight() ]
					};

					return (clickX >= range.x[0] && clickX <= range.x[1]) && (clickY >= range.y[0] && clickY <= range.y[1])

				});
				
				list = $list.map(function() {
					return this.nodeName + ' ' + this.className
				}).get();
				toggleSelected($list[$list.length-1]);
				return false;
			});
		}

		// Toggle the visual editors selected element
		function toggleSelected(e)
		{
			if (typeof e.selected == undefined || !e.selected)
			{
				//visualEditorWindow.alert("selecting");
				unsetSelected(e);
				setSelected(e);
			}
			else
			{
				//visualEditorWindow.alert("unselecting");
				unsetSelected(e);
			}
		}
		
		// Unset the selected element of the document of e
		function unsetSelected(e)
		{
			if (typeof e.ownerDocument.selectedElement != undefined)
			{
				deselect(e.ownerDocument.selectedElement);
				e.ownerDocument.selectedElement = null;
				e.ownerDocument.selectedEventCount = 0;
			}
		}
		
		// Make e not selected
		function deselect(e)
		{
			if (e != null)
			{
				e.selected = false;
				e.style.border = e.oldBorderStyle;
				delete e.oldBorderStyle;
			}
		}
		
		// Make e the selected element
		function setSelected(e)
		{
			if (typeof e.ownerDocument.selectedElement != undefined && e.ownerDocument.selectedElement != null)
			{
				return;
			}
			select(e);
			e.ownerDocument.selectedElement = e;
			e.ownerDocument.selectedEventCount = e.ownerDocument.eventCount;
		}
		
		// Select the element e
		function select(e)
		{
			e.selected = true;
			e.oldBorderStyle = e.style.border;
			e.style.border = "1px solid blue";
		}
		
		// Pull the html in the view window into the editor.
		function getViewWindowHtml()
		{
			if (viewWindow != null)
			{
				//var viewHtml = viewWindow.firstChild
				setRawHtml(getDocumentHtml(viewWindow.document));
				//var viewHtml = outerHTML(viewWindow.document.documentElement);
				//var viewHtml = document.getElementById("viewWindowFrame").innetHTML;
				//var viewHtmlTxtNode = document.createTextNode(viewHtml);
				//document.getElementById("rawHtml").appendChild(viewHtmlTxtNode);
				//document.getElementById("rawHtml").value = viewHtml;
			}
		}
		
		// Pull the html from the visual editor to the editor
		function getVisualEditorWindowHtml()
		{
			if (visualEditorWindow != null)
			{
				setRawHtml(getDocumentHtml(visualEditorWindow.document));
				
			}
		}
		
		// Dead code
		// Add outer html to node
		function writeOuterHtml(node, html)
		{
			if ("outerHTML" in node)
			{
				node.outerHTML = html;
			}
			else
			{
				var div = document.createElement('div');
				div.appendChild(node.cloneNode(true));
				div.innerHTML = html;
				div = null;
			}
		}
		
		// Gets the html of doc
		function getDocumentHtml(doc)
		{
			var html = "";
			if ("doctype" in doc && null != doc.doctype)
			{
				var doctype = doc.doctype;
				html += "<!DOCTYPE";
				if ("name" in doctype && null != doctype.name)
				{
					html += " " + doctype.name;
				}
				html += " PUBLIC";
				if ("publicId" in doctype && null != doctype.publicId)
				{
					html += " \"" + doctype.publicId + "\"";
				}
				if ("systemId" in doctype && null != doctype.systemId)
				{
					html += " \"" + doctype.systemId + "\"";
				}
				html += ">";
			}
			html += outerHTML(doc.documentElement);
			return html;
		}
		
		// Gets the outer html of the node. That is the html of the node and it's inner html
		function outerHTML(node)
		{
			// if IE, Chrome take the internal method otherwise build one
		  return node.outerHTML || (
			  function(n){
				  var div = document.createElement('div'), h;
				  div.appendChild( n.cloneNode(true) );
				  h = div.innerHTML;
				  div = null;
				  return h;
			  })(node);
		}
		
		// For the editor?
		function addTab()
		{
			var selection = document.selection.createRange();
			selection.text = "\t";
		}

		window.onload = function()
		{
			document.getElementById("openViewButton").onclick = openView;
			document.getElementById("closeViewButton").onclick = closeView;
			document.getElementById("syncViewButton").onclick = getViewWindowHtml;
			document.getElementById("writeViewButton").onclick = writeViewWindowHtml;
			document.getElementById("openVisualEditorButton").onclick = openVisualEditorWindow;
			document.getElementById("closeVisualEditorButton").onclick = closeVisualEditorWindow;
			document.getElementById("syncVisualEditor").onclick = getVisualEditorWindowHtml;
			document.getElementById("writeVisualEditor").onclick = writeVisualEditorWindowHtml;
			
			//openView();
			//getViewWindowHtml();
		};
		
	</script>
</head>
<body>
	<button id="openViewButton">Open</button>
	<button id="closeViewButton">Close</button>
	<button id="syncViewButton">Sync</button>
	<button id="writeViewButton">Write</button>
	<input type="radio" name="viewType" value="window"/> Window
	<input type="radio" name="viewType" value="iframe" checked="checked"/> iFrame
	<button id="openVisualEditorButton">Open Visual Editor</button>
	<button id="closeVisualEditorButton">Close Visual Editor</button>
	<br/>
	<button id="syncVisualEditor">Sync With Visual Editor</button>
	<button id="writeVisualEditor">Write to Visual Editor</button>
	<br/><textarea id="rawHtml" cols="50" rows="15"><!DOCTYPE html PUBLIC "" "">
<html>
	<head></head>
	<body>
		<div style="width:400px;height:400px;background-color:green;"></div>
	</body>
</html></textarea><br/>
	<!--iframe id="viewWindowFrame" name="viewWindow" width="800" height="400"--></iframe>
</body>
</html>